package com.duoduo.mcc;

import java.io.Serializable;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SyncAllTest {
	public static void main(String[] args) {
		// 字符串类型可锁住
		startStringProcess("1118000", "消费者1", 2000);
		startStringProcess("1118000", "消费者2", 3000);
		startStringProcess("1118000", "消费者3", 5000);

		// 字符串类型可锁住
		startStringProcess("1118001", "消费者4", 2000);
		startStringProcess("1118001", "消费者5", 3000);
		startStringProcess("1118001", "消费者6", 5000);
		
		// Integer不超过128可锁住
		startIntegerProcess(111, "消费者7", 2000);
		startIntegerProcess(111, "消费者8", 3000);
		startIntegerProcess(111, "消费者9", 5000);
		
		// Integer超过128锁不住
		startIntegerProcess(1234, "消费者A", 2000);
		startIntegerProcess(1234, "消费者B", 3000);
		startIntegerProcess(1234, "消费者C", 5000);
		
		// Integer转换为String也锁不住
		startIntegerToStringProcess(222222, "消费者D", 2000);
		startIntegerToStringProcess(222222, "消费者E", 3000);
		startIntegerToStringProcess(222222, "消费者F", 5000);
	}

	/**
	 * 字符串类型可锁住
	 * @param key
	 * @param consumer
	 * @param waitTime
	 */
	private static void startStringProcess(String key, String consumer, long waitTime) {
		SyncProcessThread<String> pt = new SyncProcessThread<String>(key, consumer, waitTime);
		Thread t = new Thread(pt);
		t.start();
	}

	/**
	 * key<=128可锁住，key>128锁不住
	 * @param key
	 * @param consumer
	 * @param waitTime
	 */
	private static void startIntegerProcess(int key, String consumer, long waitTime) {
		SyncProcessThread<Integer> pt = new SyncProcessThread<Integer>(key, consumer, waitTime);
		Thread t = new Thread(pt);
		t.start();
	}

	
	/**
	 * Integer转换为String也锁不住
	 * @param key
	 * @param consumer
	 * @param waitTime
	 */
	private static void startIntegerToStringProcess(int key, String consumer, long waitTime) {
		String value = String.valueOf(key); // "" + key;
		SyncProcessThread<String> pt = new SyncProcessThread<String>(value, consumer, waitTime);
		Thread t = new Thread(pt);
		t.start();
	}
}


class SyncProcessThread<T extends Serializable> implements Runnable {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private T key;
	private String consumer;
	private long waitTime;
	private Random random;

	public SyncProcessThread(T key, String consumer, long waitTime) {
		this.key = key;
		this.consumer = consumer;
		this.waitTime = waitTime;

		this.random = new Random(System.currentTimeMillis());
	}

	public void doSomething(long time) {
		logger.info("{} 开始处理 {} 对应的消息", consumer, key);

		try {
			Thread.sleep(time);
		} catch (Exception e) {

		}
		logger.info("{} 完成处理 {} 对应的消息", consumer, key);
	}

	public void run() {
		while (true) {
			logger.info("{} 请求处理 {} >>>>>>", consumer, key);
			synchronized (key) {
				logger.info("{} 开始执行 {} 对应的消息", consumer, key);
				doSomething(waitTime);
			}

			try {
				Thread.sleep(200 + random.nextInt(200));
			} catch (Exception e) {

			}
		}
	}

}
